// import './pattern-matting';
// import './construct-transform';
// import './recursion';
// import './calculate';
// import './union-types';
// import './special-types';
//
type MergeValues<Lhs, Rhs> = Lhs extends Rhs
  ? Lhs
  : Rhs extends unknown[]
  ? [Lhs, ...Rhs]
  : [Lhs, Rhs];

type Merge<T extends Record<string, any>, R extends Record<string, any>> = {
  [K in keyof T | keyof R]: K extends keyof T
    ? K extends keyof R
      ? MergeValues<T[K], R[K]>
      : T[K]
    : K extends keyof R
    ? R[K]
    : never;
};

type MakeProps<A extends string, B> = {
  [K in A]: B;
};

type GetProps<T extends string> = T extends `${infer Fst}=${infer R}`
  ? MakeProps<Fst, R>
  : Record<string, any>;

type GetQuery<T extends string> = T extends `${infer Fst}&${infer R}`
  ? Merge<GetProps<Fst>, GetQuery<R>>
  : GetProps<T>;

function getQuery<T extends string>(query: T): GetQuery<T> {
  if (!query || !query.length) {
    return {} as any;
  }
  const params = query.split('&');
  const o: Record<string, any> = {};
  params.forEach(parameter => {
    const [k, v] = parameter.split('=');
    if (o[k]) {
      if (Array.isArray(o[k])) {
        o[k].push(v);
      } else {
        o[k] = [o[k], v];
      }
    } else {
      o[k] = v;
    }
  });
  return o as any;
}
const query = getQuery('a=1');

console.log(query.a);

function FirstFactorial(num: number): number {
  let n = 1;
  for (let i = num; i > 0; --i) {
    n *= i;
  }
  return n;
}

console.log(FirstFactorial(8));

function FirstReverse(str: string): string {
  let temp = '';
  for (let i = str.length; i >= 0; --i) {
    temp += str.charAt(i);
  }
  return temp;
}

console.log(FirstReverse('coderbyte'));
